package com.duowan.cms.common.service;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.json.simple.parser.JSONParser;

import com.duowan.cms.common.exception.BaseUncheckedException;

public class JsonToDtoConvertor<O> {
	private static Logger logger = Logger.getLogger(JsonToDtoConvertor.class);
	/**
	 * 从Json字符串取值填充Dto失败
	 * @param request
	 * @param bean
	 */
	public static <O> void convert(HttpServletRequest request, O bean)  {
		JSONParser parser = new JSONParser();
		try {
			String jsonStr = getJsonData(request);
			// Json字符串的格式为{ID:{type:int,fieldName:fieldName,value:dataValue},......}
			// 解析出来的格式为Map<id,Map>
			Map jsonMap = (Map) parser.parse(jsonStr.trim());
			Iterator it = jsonMap.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry entry = (Map.Entry) it.next();
				Object key = entry.getKey();
				Map formElementInfoMap = (Map) entry.getValue();
				instantiate( (Map) entry.getValue() , bean );
			}
		} catch (Exception e) {
			logger.error("从Json字符串取值填充Dto失败" , e );
			throw new BaseUncheckedException("从Json字符串取值填充Dto失败:详细请查看日志！" );
		}

	}

	private static <O> void instantiate(Map formElementInfoMap, O bean)
				throws IntrospectionException, IllegalArgumentException, IllegalAccessException,
				InvocationTargetException, ClassNotFoundException, java.text.ParseException {
		BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
		PropertyDescriptor[] propertieDescritors = beanInfo.getPropertyDescriptors();
		String prop;
		for (PropertyDescriptor propertyDescriptor : propertieDescritors) {
			Method writeMethod = propertyDescriptor.getWriteMethod();
			prop = propertyDescriptor.getName();
			if ( String.valueOf(formElementInfoMap.get("fieldName")).equals(prop)) {
				writeMethod.invoke(bean, 
					new Object[] { 
							cast(String.valueOf(formElementInfoMap.get("type")), String.valueOf(formElementInfoMap.get("value")))  
					});
			}
		}
	}

	private static Object cast(String type, String dataValue) throws java.text.ParseException,
				ClassNotFoundException {
		if (type.equals("String")) {
			return dataValue;
		}
		if (type.equals("int")) {
			return Integer.parseInt(dataValue);
		}
		if (type.equals("date")) {
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return dateFormat.parse(dataValue);
		}
		if (type.equals("double")) {
			return Double.parseDouble(dataValue);
		}
		return Class.forName(type).cast(dataValue);
	}

	/**
	 * 通过IO流读取输入数据
	 * 
	 * @param request
	 * @throws ServletException
	 * @throws IOException
	 */
	private static String getJsonData(HttpServletRequest request) throws ServletException,
				IOException {
		ServletInputStream servletInputStream = request.getInputStream();
		byte[] charArray = new byte[1024]; // 所有内容读到此数组中
		StringBuffer strBuffer = new StringBuffer("");
		while ((servletInputStream.read(charArray)) != -1) {
			strBuffer.append(new String(charArray, "UTF-8"));
		}
		System.out.println("通过IO流读取输入数据:" + strBuffer.toString());
		return strBuffer.toString();
	}

}
